import os
import copy
import time
import json
import concurrent.futures
from datetime import datetime
from omegaconf import OmegaConf, DictConfig
from DrissionPage import ChromiumOptions, Chromium
import hydra

from helper.cursor_register import CursorRegister
from helper.email import OutlookWeb
from helper.account_manager import AccountManager

# 账号配置文件路径
OUTLOOK_ACCOUNTS_JSON = "outlook_accounts.json"
REGISTERED_ACCOUNTS_JSON = "registered_accounts.json"

# 参数设置
hide_account_info = os.getenv('HIDE_ACCOUNT_INFO', 'false').lower() == 'true'
enable_headless = os.getenv('ENABLE_HEADLESS', 'false').lower() == 'true'
enable_browser_log = os.getenv('ENABLE_BROWSER_LOG', 'true').lower() == 'true' or not enable_headless

def load_outlook_accounts():
    """从JSON文件加载Outlook账号"""
    if not os.path.exists(OUTLOOK_ACCOUNTS_JSON):
        # 如果文件不存在，创建模板文件
        template = {
            "accounts": [
                {"email": "example@outlook.com", "password": "your_password"}
            ]
        }
        with open(OUTLOOK_ACCOUNTS_JSON, 'w', encoding='utf-8') as file:
            json.dump(template, file, indent=4, ensure_ascii=False)
        print(f"[注册] 已创建Outlook账号模板文件: {OUTLOOK_ACCOUNTS_JSON}")
        print("[注册] 请在文件中添加Outlook账号后重新运行程序")
        return []
    
    accounts = []
    try:
        with open(OUTLOOK_ACCOUNTS_JSON, 'r', encoding='utf-8') as file:
            data = json.load(file)
            if "accounts" in data and isinstance(data["accounts"], list):
                for account in data["accounts"]:
                    if "email" in account and "password" in account:
                        accounts.append({
                            'email': account['email'],
                            'password': account['password']
                        })
    except Exception as e:
        print(f"[注册] 读取Outlook账号文件失败: {str(e)}")
        return []
    
    print(f"[注册] 已从{OUTLOOK_ACCOUNTS_JSON}加载{len(accounts)}个Outlook账号")
    return accounts

def generate_password():
    """生成随机密码"""
    import random
    import string
    # 生成8-12位密码，包含字母、数字和特殊字符
    length = random.randint(8, 12)
    chars = string.ascii_letters + string.digits + '!@#$%^&*'
    return ''.join(random.choice(chars) for _ in range(length))

def register_cursor_core(register_config, options, outlook_account=None):
    """注册Cursor核心函数"""
    try:
        # 尝试打开浏览器
        browser = Chromium(options)
    except Exception as e:
        print(e)
        return None

    # 使用传入的Outlook账号
    if outlook_account:
        email_address = outlook_account['email']
        email_password = outlook_account['password']
        print(f"[注册] 使用Outlook账号: {email_address}")
        email_server = OutlookWeb(browser, email_address, email_password)
    else:
        print("[注册] 未提供有效的Outlook账号")
        if browser:
            browser.quit(force=True, del_data=True)
        return None

    # 生成Cursor账号的密码
    cursor_password = generate_password()

    register = CursorRegister(browser, email_server)
    # 第二个参数传递密码
    tab_signin, status = register.sign_in(email_address, cursor_password)
    token = register.get_cursor_cookie(tab_signin)

    if status and not enable_browser_log:
        register.browser.quit(force=True, del_data=True)
        
    if status and not hide_account_info:
        print(f"[注册] Cursor 邮箱: {email_address}")
        print(f"[注册] Cursor 密码: {cursor_password}")
        print(f"[注册] Cursor 令牌: {token}")

    # 确保返回结果中包含密码
    ret = {
        "username": email_address,
        "outlook_password": outlook_account.get('password', ''),
        "cursor_password": cursor_password,
        "token": token
    }

    return ret

def save_registered_accounts(results):
    """保存已注册账号到JSON文件"""
    if not results:
        return
        
    # 读取现有数据
    existing_accounts = {}
    if os.path.exists(REGISTERED_ACCOUNTS_JSON):
        try:
            with open(REGISTERED_ACCOUNTS_JSON, 'r', encoding='utf-8') as file:
                data = json.load(file)
                if "accounts" in data and isinstance(data["accounts"], list):
                    for account in data["accounts"]:
                        if "username" in account:
                            existing_accounts[account["username"]] = account
        except Exception as e:
            print(f"[注册] 读取已注册账号文件失败: {str(e)}")
    
    # 更新数据
    for result in results:
        if result and "username" in result and result["token"]:
            existing_accounts[result["username"]] = result
    
    # 保存数据
    try:
        data = {"accounts": list(existing_accounts.values())}
        with open(REGISTERED_ACCOUNTS_JSON, 'w', encoding='utf-8') as file:
            json.dump(data, file, indent=4, ensure_ascii=False)
        print(f"[注册] 已保存 {len(results)} 个新注册账号到 {REGISTERED_ACCOUNTS_JSON}")
    except Exception as e:
        print(f"[注册] 保存已注册账号失败: {str(e)}")

def register_cursor(register_config):
    """批量注册Cursor账号的主函数"""
    options = ChromiumOptions()
    options.auto_port()
    options.new_env()
    # 使用turnstilePatch以绕过验证码检测
    turnstile_patch_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "turnstilePatch"))
    options.add_extension(turnstile_patch_path)

    # 读取Outlook账号
    outlook_accounts = load_outlook_accounts()
    if not outlook_accounts:
        print(f"[注册] 未找到有效的Outlook账号，请在 {OUTLOOK_ACCOUNTS_JSON} 中添加账号。")
        return []
    
    # 设置无头模式（可选）
    if enable_headless: 
        from platform import platform
        if platform == "linux" or platform == "linux2":
            platformIdentifier = "X11; Linux x86_64"
        elif platform == "darwin":
            platformIdentifier = "Macintosh; Intel Mac OS X 10_15_7"
        elif platform == "win32":
            platformIdentifier = "Windows NT 10.0; Win64; x64"
        # 设置Chrome版本，建议与本地版本一致
        chrome_version = "130.0.0.0"        
        options.set_user_agent(f"Mozilla/5.0 ({platformIdentifier}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/{chrome_version} Safari/537.36")
        options.headless()
    
    # 根据配置或可用账号确定实际注册数量
    number = min(register_config.number, len(outlook_accounts))
    max_workers = min(register_config.max_workers, number)
    
    print(f"[注册] 开始注册 {number} 个账号，使用 {max_workers} 个线程")    
    # 使用多线程执行注册
    results = []
    with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
        futures = []
        for idx in range(number):
            if idx < len(outlook_accounts):
                # 使用JSON中的账号
                current_account = outlook_accounts[idx]
                register_config_thread = copy.deepcopy(register_config)
                options_thread = copy.deepcopy(options)
                futures.append(executor.submit(register_cursor_core, register_config_thread, options_thread, current_account))
            
        for future in concurrent.futures.as_completed(futures):
            result = future.result()
            if result is not None:
                results.append(result)

    # 过滤掉注册失败的结果
    results = [result for result in results if result["token"] is not None]

    # 保存已注册账号
    if results:
        save_registered_accounts(results)
        print(f"[注册] 成功注册 {len(results)} 个账号")

    return results

@hydra.main(config_path="config", config_name="config", version_base=None)
def main(config: DictConfig):
    """主函数入口"""
    register_cursor(config.register)

if __name__ == "__main__":
    main()
